package com.eduagent.xwqeduagent.controller;

import com.eduagent.xwqeduagent.api.DocumentTranslation.DocumentTranslationClient;
import com.eduagent.xwqeduagent.api.DocumentTranslation.constant.DocumentTranslationConstant;
import com.eduagent.xwqeduagent.api.DocumentTranslation.model.DocumentInfo;
import com.eduagent.xwqeduagent.api.DocumentTranslation.model.DocumentTranslationLanguage;
import com.eduagent.xwqeduagent.api.DocumentTranslation.model.DocumentTranslationRequest;
import com.eduagent.xwqeduagent.common.BaseResponse;
import com.eduagent.xwqeduagent.exception.BusinessException;
import com.eduagent.xwqeduagent.exception.ErrorCode;
import com.eduagent.xwqeduagent.utils.CosUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import lombok.AllArgsConstructor;
import lombok.Data;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.HashMap;
import java.net.HttpURLConnection;

/**
 * 文档翻译控制器
 */
@RestController
@RequestMapping("/document-translation")
@Tag(name = "文档翻译", description = "提供多种格式的文档翻译功能，支持PDF、Word、Excel、PowerPoint等格式")
@Slf4j
public class DocumentTranslationController {

    @Autowired
    private DocumentTranslationClient documentTranslationClient;

    @Value("${edu.ai.document.tempDir}")
    private String tempDir;
    
    @Autowired
    private CosUtils cosUtils;

    /**
     * 上传并翻译文档
     *
     * @param file 要翻译的文件
     * @param from 源语言代码
     * @param to 目标语言代码
     * @param realmCode 领域代码（可选）：0-通用，1-医疗，2-专利
     * @param processingMode PDF处理模式（可选）：0-可编辑PDF，1-扫描版PDF，2-自动检测
     * @return 翻译任务ID（fileNo）
     */
    @Operation(summary = "上传并翻译文档", description = "上传文档并开始翻译，支持PDF、Word、Excel、PowerPoint等格式")
    @PostMapping("/upload")
    public Map<String, Object> uploadAndTranslate(
            @Parameter(description = "要翻译的文件") @RequestParam("file") MultipartFile file,
            @Parameter(description = "源语言代码，如zh(中文)、en(英文)等") @RequestParam String from,
            @Parameter(description = "目标语言代码，如zh(中文)、en(英文)等") @RequestParam String to,
            @Parameter(description = "领域代码（可选）：0-通用，1-医疗，2-专利") @RequestParam(required = false) Integer realmCode,
            @Parameter(description = "PDF处理模式（可选，仅PDF文件适用）：0-可编辑PDF，1-扫描版PDF，2-自动检测") @RequestParam(required = false) Integer processingMode) {
        
        Map<String, Object> response = new HashMap<>();
        
        try {
            // 检查目录是否存在，不存在则创建
            Path tempPath = Paths.get(tempDir);
            if (!Files.exists(tempPath)) {
                Files.createDirectories(tempPath);
            }
            
            // 保存上传的文件到临时目录
            String originalFilename = file.getOriginalFilename();
            String tempFileName = UUID.randomUUID() + "_" + originalFilename;
            Path filePath = Paths.get(tempDir, tempFileName);
            file.transferTo(filePath.toFile());
            
            // 构建翻译请求
            DocumentTranslationRequest request = DocumentTranslationRequest.builder()
                    .from(from)
                    .to(to)
                    .file(filePath.toFile())
                    .realmCode(realmCode)
                    .processingMode(processingMode)
                    .build();
            
            // 上传并翻译文件
            String fileNo = documentTranslationClient.uploadAndTranslate(request);
            
            if (fileNo == null) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "文档翻译请求失败");
            }
            
            // 构建符合要求的返回格式
            response.put("code", 200);
            response.put("msg", "成功");
            
            Map<String, String> dataMap = new HashMap<>();
            dataMap.put("fileNo", fileNo);
            response.put("data", dataMap);
            
            return response;
        } catch (BusinessException e) {
            log.error("文档翻译业务异常: {}", e.getMessage());
            response.put("code", e.getCode());
            response.put("msg", e.getMessage());
            response.put("data", null);
            return response;
        } catch (IOException e) {
            log.error("文件处理异常: {}", e.getMessage(), e);
            response.put("code", 500);
            response.put("msg", "文件处理异常: " + e.getMessage());
            response.put("data", null);
            return response;
        } catch (Exception e) {
            log.error("文档翻译异常: {}", e.getMessage(), e);
            response.put("code", 500);
            response.put("msg", "文档翻译异常: " + e.getMessage());
            response.put("data", null);
            return response;
        }
    }

    /**
     * 获取翻译进度
     *
     * @param fileNo 文件编号
     * @return 文档信息，包括翻译进度
     */
    @Operation(summary = "获取翻译进度", description = "根据文件编号查询翻译进度和状态")
    @GetMapping("/status/{fileNo}")
    public BaseResponse<DocumentInfo> getStatus(
            @Parameter(description = "文件编号") @PathVariable String fileNo) {
        
        try {
            DocumentInfo info = documentTranslationClient.getDocumentInfo(fileNo);
            
            if (info == null) {
                return new BaseResponse<>(404, null, "未找到该任务或任务已过期");
            }
            
            return new BaseResponse<>(200, info, "获取任务状态成功");
        } catch (Exception e) {
            log.error("获取翻译状态异常: {}", e.getMessage(), e);
            return new BaseResponse<>(500, null, "获取翻译状态异常: " + e.getMessage());
        }
    }


    /**
     * 获取翻译文件下载链接
     *
     * @param fileNo 文件编号
     * @param type 下载类型（可选）：0-原文件，1-译文件（默认），2-双语文件
     * @return COS文件链接
     */
    @Operation(summary = "获取翻译文件COS链接", description = "获取翻译文件的COS存储链接")
    @GetMapping("/download-url/{fileNo}")
    public BaseResponse<String> getDownloadUrl(
            @Parameter(description = "文件编号") @PathVariable String fileNo,
            @Parameter(description = "下载类型（可选）：0-原文件，1-译文件（默认），2-双语文件") 
            @RequestParam(required = false, defaultValue = "1") Integer type) {
        
        try {
            // 获取原始下载链接
            String originalUrl = documentTranslationClient.getDownloadUrl(fileNo, type);
            
            if (originalUrl == null || originalUrl.isEmpty()) {
                return new BaseResponse<>(404, null, "未找到该任务或任务已过期");
            }
            
            // 获取文件名和类型
            DocumentInfo info = documentTranslationClient.getDocumentInfo(fileNo);
            String fileName = info != null ? info.getFileName() : fileNo + "_" + type + ".pdf";
            
            // 创建临时文件
            String tempFileName = UUID.randomUUID() + "_" + fileName;
            Path tempFilePath = Paths.get(tempDir, tempFileName);
            File tempFile = tempFilePath.toFile();
            
            // 下载文件到本地
            URL url = new URL(originalUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            
            // 确保跟随重定向
            connection.setInstanceFollowRedirects(true);
            
            // 获取内容类型
            String contentType = connection.getContentType();
            log.info("下载文档的内容类型: {}", contentType);
            
            // 获取文件大小
            int contentLength = connection.getContentLength();
            
            try (InputStream inputStream = connection.getInputStream()) {
                Files.copy(inputStream, tempFilePath, StandardCopyOption.REPLACE_EXISTING);
            }
            
            // 上传到COS，确保传递正确的内容类型
            String cosUrl;
            if (contentType != null && !contentType.isEmpty()) {
                // 如果有内容类型，使用带内容类型的上传方法
                try (InputStream fileInputStream = Files.newInputStream(tempFilePath)) {
                    cosUrl = cosUtils.uploadFile(fileInputStream, fileName, contentType, "document-translation", tempFile.length());
                }
            } else {
                // 否则使用文件上传
                cosUrl = cosUtils.uploadFile(tempFile, "document-translation");
            }
            
            // 删除临时文件
            Files.deleteIfExists(tempFilePath);
            
            return new BaseResponse<>(200, cosUrl, "获取COS链接成功");
        } catch (Exception e) {
            log.error("处理翻译文件异常: {}", e.getMessage(), e);
            return new BaseResponse<>(500, null, "处理翻译文件异常: " + e.getMessage());
        }
    }

    /**
     * 中断翻译任务
     *
     * @param fileNo 文件编号
     * @return 操作结果
     */
    @Operation(summary = "中断翻译任务", description = "中断正在进行的翻译任务")
    @PostMapping("/interrupt/{fileNo}")
    public BaseResponse<Boolean> interruptTranslation(
            @Parameter(description = "文件编号") @PathVariable String fileNo) {
        
        try {
            boolean success = documentTranslationClient.interruptTranslation(fileNo);
            
            if (success) {
                return new BaseResponse<>(200, true, "成功中断翻译任务");
            } else {
                return new BaseResponse<>(400, false, "中断翻译任务失败");
            }
        } catch (Exception e) {
            log.error("中断翻译任务异常: {}", e.getMessage(), e);
            return new BaseResponse<>(500, false, "中断翻译任务异常: " + e.getMessage());
        }
    }

    /**
     * 删除翻译任务
     *
     * @param fileNo 文件编号
     * @return 操作结果
     */
    @Operation(summary = "删除翻译任务", description = "删除翻译任务及相关文件")
    @DeleteMapping("/{fileNo}")
    public BaseResponse<Boolean> deleteTranslation(
            @Parameter(description = "文件编号") @PathVariable String fileNo) {
        
        try {
            boolean success = documentTranslationClient.deleteFile(fileNo);
            
            if (success) {
                return new BaseResponse<>(200, true, "成功删除翻译任务");
            } else {
                return new BaseResponse<>(400, false, "删除翻译任务失败");
            }
        } catch (Exception e) {
            log.error("删除翻译任务异常: {}", e.getMessage(), e);
            return new BaseResponse<>(500, false, "删除翻译任务异常: " + e.getMessage());
        }
    }

    /**
     * 获取支持的语言列表
     *
     * @return 支持的语言列表
     */
    @Operation(summary = "获取支持的语言列表", description = "获取文档翻译支持的语言列表及代码")
    @GetMapping("/languages")
    public BaseResponse<List<LanguageInfo>> getSupportedLanguages() {
        List<LanguageInfo> languages = new ArrayList<>();
        
        // 添加主要语言
        languages.add(new LanguageInfo("CHINESE_SIMPLIFIED", "简体中文", "zh"));
        languages.add(new LanguageInfo("CHINESE_TRADITIONAL", "繁体中文", "cht"));
        languages.add(new LanguageInfo("ENGLISH", "英语", "en"));
        languages.add(new LanguageInfo("JAPANESE", "日语", "ja"));
        languages.add(new LanguageInfo("KOREAN", "韩语", "ko"));
        languages.add(new LanguageInfo("RUSSIAN", "俄语", "ru"));
        languages.add(new LanguageInfo("ARABIC", "阿拉伯语", "ar"));
        languages.add(new LanguageInfo("FRENCH", "法语", "fr"));
        languages.add(new LanguageInfo("GERMAN", "德语", "de"));
        languages.add(new LanguageInfo("SPANISH", "西班牙语", "es"));
        languages.add(new LanguageInfo("PORTUGUESE", "葡萄牙语", "pt"));
        languages.add(new LanguageInfo("ITALIAN", "意大利语", "it"));
        languages.add(new LanguageInfo("THAI", "泰语", "th"));
        languages.add(new LanguageInfo("VIETNAMESE", "越南语", "vi"));
        languages.add(new LanguageInfo("INDONESIAN", "印尼语", "id"));
        languages.add(new LanguageInfo("MALAY", "马来语", "ms"));
        languages.add(new LanguageInfo("HINDI", "印地语", "hi"));
        languages.add(new LanguageInfo("TURKISH", "土耳其语", "tr"));
        languages.add(new LanguageInfo("DUTCH", "荷兰语", "nl"));
        languages.add(new LanguageInfo("POLISH", "波兰语", "pl"));
        languages.add(new LanguageInfo("SWEDISH", "瑞典语", "sv"));
        languages.add(new LanguageInfo("DANISH", "丹麦语", "da"));
        languages.add(new LanguageInfo("NORWEGIAN", "挪威语", "no"));
        languages.add(new LanguageInfo("FINNISH", "芬兰语", "fi"));
        languages.add(new LanguageInfo("GREEK", "希腊语", "el"));
        languages.add(new LanguageInfo("HEBREW", "希伯来语", "he"));
        
        return new BaseResponse<>(200, languages, "获取支持的语言列表成功");
    }

    /**
     * 语言信息类
     */
    @Data
    @AllArgsConstructor
    public static class LanguageInfo {
        /**
         * 语言枚举名称
         */
        private String code;
        
        /**
         * 语言中文名称
         */
        private String chineseName;
        
        /**
         * 语言代码
         */
        private String languageCode;
    }
} 